events {
        worker_connections 768;
        multi_accept on;
}

http {
    upstream app {
        server web:8000;
    }

    upstream ws_server {
        server distributor:4321;
    }

    upstream socket_server {
        server multi_connection:9001;
    }

    server {
        listen 80 default_server;
        listen [::]:80 default_server;

        # listen on both hosts
        server_name _;

        # redirect to the https host (declared below)
        return 301 https://$host$request_uri;
    }

    server {
        listen 9001 ssl;
        listen [::]:9443 ssl;

        server_name _;
        ssl_certificate      /etc/certs/fullchain.pem;
        ssl_certificate_key  /etc/certs/key.pem;
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

        location / {
            try_files $uri @proxy_to_socket;
        }

        location @proxy_to_socket {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_redirect off;

            proxy_pass http://socket_server;
        }
    }

    server {
        listen 443 http2 ssl;
        listen [::]:443 ssl;

        server_name _;
        ssl_certificate      /etc/certs/fullchain.pem;
        ssl_certificate_key  /etc/certs/key.pem;

        # Improve HTTPS performance with session resumption
        ssl_session_cache shared:SSL:10m;
        ssl_session_timeout 10m;

        # Enable server-side protection against BEAST attacks
        ssl_protocols TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384";

        # RFC-7919 recommended: https://wiki.mozilla.org/Security/Server_Side_TLS#ffdhe4096
        #ssl_dhparam /etc/ssl/ffdhe4096.pem;
        #ssl_ecdh_curve secp521r1:secp384r1;

        # Aditional Security Headers
        # ref: https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

        # ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options
        add_header X-Frame-Options DENY always;

        # ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
        add_header X-Content-Type-Options nosniff always;

        # ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection
        add_header X-Xss-Protection "1; mode=block" always;

        # Enable OCSP stapling
        # ref. http://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox
        ssl_stapling on;
        ssl_stapling_verify on;
        ssl_trusted_certificate /etc/certs/fullchain.pem;
        resolver 1.1.1.1 1.0.0.1 [2606:4700:4700::1111] [2606:4700:4700::1001] valid=300s; # Cloudflare
        resolver_timeout 5s;

        location / {
            try_files $uri @proxy_to_app;
        }

        location /ws/ {
            try_files $uri @proxy_to_ws;
        }

        location @proxy_to_ws {
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_redirect off;

            proxy_pass   http://ws_server;
        }

        # django app
        location @proxy_to_app {
            proxy_set_header X-Forwarded-Proto https;
            proxy_set_header X-Url-Scheme $scheme;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;

            proxy_pass   http://app;
        }
    }
}